#include <stdio.h>
#include <stdlib.h>
#include "dr_api.h" 

#define BUF_SIZE 512

static file_t logFile;
static char logBuf[BUF_SIZE];

static bool event_pre_syscall(void *, int); 
static void event_exit(void);

DR_EXPORT void dr_init(client_id_t id) 
{ 
	logFile = dr_open_file("C:/InterceptFileName.log", DR_FILE_WRITE_OVERWRITE);

	if (logFile == INVALID_FILE)
	{
		dr_messagebox("Fail to open a log file at C:/");
		exit(1);
	}

	dr_register_pre_syscall_event(event_pre_syscall); 
	dr_register_exit_event(event_exit);
} 

/* Only for Windows XP */

static bool event_pre_syscall(void *drcontext, int sysnum){ 
	switch (sysnum) 
	{

	/* NtCreateFile */ 

	case 0x25: 
		{

			/*
			* Struct/Function prototype we needed.
			*
			* NtCreateFile(
			*	OUT	PHANDLE				FileHandle,
			*	IN	ACCESS_MASK			DesiredAccess,
			*	IN	POBJECT_ATTRIBUTES	ObjectAttributes,		(*)
			*	OUT PIO_STATUS_BLOCK	IoStatusBlock,
			*	IN	PLARGE_INTEGER		AllocationSize	OPTIONAL,
			*	IN	ULONG				FileAttributes,
			*	IN	ULONG				ShareAccess,
			*	IN	ULONG				CreateDisposition,
			*	IN	ULONG				CreateOptions,
			*	IN	PVOID				EaBuffer		OPTIONAL,
			*	IN	ULONG				EaLength
			*	);
			* 
			* struct _OBJECT_ATTRIBUTES{
			*   ULONG					Length;
			*   HANDLE					RootDirectory;
			*	PUNICODE_STRING			ObjectName;				(*)
			*   ULONG					Attributes;
			*   PVOID					SecurityDescriptor;
			*	PVOID					SecurityQualityOfService;
			* } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
			* 
			* struct _LSA_UNICODE_STRING {
			*   USHORT					Length;
			*   USHORT					MaximumLength;
			*   PWSTR					Buffer;					(*)
			* } LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING;
			*/
 
			long *ptemp; 

			ptemp = (long *) dr_syscall_get_param(drcontext, 2); 

			ptemp = (long *) (*(ptemp+2)); 

			ptemp = (long *) (*(ptemp+1));

			sprintf(logBuf, "NtCreatFile, Filename: %ls", (WCHAR *)ptemp);

			dr_fprintf(logFile, "%s\n", logBuf);

			break; 
		} 
	default: 
		break; 
	} 

	return true; 
} 

static void event_exit(void){
	dr_flush_file(logFile);
	dr_close_file(logFile);
}